home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / Found / FWString / Include / FWCharIt.h < prev    next >
Encoding:
Text File  |  1996-08-16  |  9.7 KB  |  285 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWCharIt.h
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #ifndef FWCHARIT_H
  11. #define FWCHARIT_H
  12.  
  13. #ifndef   FWEXCLIB_H
  14. #include "FWExcLib.h"
  15. #endif
  16.  
  17. #ifndef FWPRIDEB_H
  18. #include "FWPriDeb.h"
  19. #endif
  20.  
  21. #ifndef FWCHARAC_H
  22. #include "FWCharac.h"
  23. #endif
  24.  
  25. #ifndef SLLOCALE_H
  26. #include "SLLocale.h"
  27. #endif
  28.  
  29. #ifndef SLCHARIT_H
  30. #include "SLCharIt.h"
  31. #endif
  32.  
  33. //========================================================================================
  34. // Forward Declarations
  35. //========================================================================================
  36.  
  37. class FW_OMemoryRunReader;
  38. class FW_OMemoryRunWriter;
  39. class FW_OTextRunReader;
  40. class FW_OTextRunWriter;
  41.  
  42. //========================================================================================
  43. //                            Design Notes for Text Readers
  44. //
  45. //    Text readers are designed to be as fast and light-weight as possible.  We assume
  46. //    that in over 90% of the usage of Text readers, the reader will be used to make
  47. //    one sequential pass through the data structure, operating on one character at a time.
  48. //    The first design goal is therefore:
  49. //        1) Make GetCharacterAndAdvance be as efficient as possible.
  50. //    In order to achieve full efficiency, we need to minimize overhead for error checking
  51. //    for reading past the end of the data structure.  We therefore set this requirement:
  52. //        2) Rely on a clear contract to minimize overhead.  It is not necessary for
  53. //        iterators to fail gracefully when misused.
  54. //    As stated above, in 90% of the cases, the text is read in one forward pass.  However,
  55. //  reading backward through the text is a surprisingly large portion of the remaining
  56. //  10%, and if not supported, significantly reduces the usefulness of readers.  We
  57. //    therefore attempt to achieve this goal:
  58. //        3) Make "put back" a relatively efficient operation.  Make it possible to
  59. //        read backwards through the data structure.
  60. //    Often a client iterating over text will want to note the position of some character
  61. //    or token in the text.  We therefore set another goal:
  62. //        4) Support GetPosition ('tell') and SetPosition ('seek') operations.
  63. //    This last goal implies a specific need to handle the case where a client attempts to
  64. //    seek past the end of the text data structure.  In this case, to achieve efficiency,
  65. //    we invoke 2), by setting this requirement:
  66. //        5) It is acceptable to state in the contract that an attempt to SetPosition to
  67. //        an arbitrary position may fail.  However, a client can use GetLength to find
  68. //        the length of the data structure; it is safe to SetPosition to any value greater
  69. //        than or equal to zero, and less than the length of the data structure.
  70. //========================================================================================
  71.  
  72. //========================================================================================
  73. //    CLASS FW_CTextReader
  74. //
  75. //    A base class for iterators that read over a data structure containing characters.
  76. //
  77. //    It is possible to create a TextReader to read over any text data structure, as long
  78. //    as the following constraints are met:
  79. //
  80. //    1) It must be possible to get the total number of characters in the data structure
  81. //       at the time the text reader is constructed.
  82. //    1a) Of course, we assume that the length and content of the data structure does
  83. //        not change while the iterator is being used!
  84. //    2) The data members fStart, fLimit, and fNext are updated
  85. //
  86. //
  87. //    Invariant:
  88. //        ((fStart<=fNext) && (fNext<fLimit))
  89. //     || ((fStart-1==fNext) && (fBufferSum==0))
  90. //     || ((fNext==fLimit) && (fBufferSum==GetLength())
  91. //========================================================================================
  92.  
  93. class FW_CTextReader
  94. {
  95. public:
  96.     FW_DECLARE_AUTO(FW_CTextReader)
  97.  
  98.     // ----- General
  99.     
  100.     virtual ~ FW_CTextReader();
  101.     FW_CTextReader(FW_OTextRunReader* adoptedReader);
  102.     FW_CTextReader(FW_HTextReader useReader);
  103.     
  104.     operator FW_HTextReader()
  105.         { return fRep; }
  106.  
  107.     FW_ByteCount GetPosition();
  108.         // Get the current byte position, where 0 is first position in data structure.
  109.  
  110.     void SetPosition(FW_ByteCount position);
  111.         // Set the byte position to position.
  112.         // The result is undefined if position is outside the bounds of the data structure.
  113.  
  114.     FW_ByteCount GetByteLength();
  115.         // Get number of bytes in data structure.
  116.     
  117.     const char* PeekByte() const;
  118.         // Return a pointer to the current byte without advancing. Can be used for lookahead.
  119.  
  120.     // ----- Character-by-character iteration
  121.  
  122.     void Advance();
  123.         // Advance by one character.
  124.         
  125.     void Backup();
  126.         // Backup by one character.
  127.     
  128.     FW_LChar PeekCharacter();
  129.         // Return the current character without advancing.  
  130.         // Can be used for lookahead.
  131.  
  132.     FW_LChar GetCharacterAndAdvance();
  133.         // Get the current character and advance.
  134.  
  135.     FW_LChar BackupAndGetCharacter();
  136.         // Backup and get previous character (byte).
  137.  
  138.     FW_LChar GetCharacterAndAdvance(FW_ByteCount& bytesInChar);
  139.         // Get the current character and advance.
  140.     
  141.     FW_LChar PeekCharacter(FW_ByteCount& bytesInChar);
  142.         // Return the current character without advancing. 
  143.  
  144.     FW_LChar BackupAndGetCharacter(FW_ByteCount& bytesInChar);
  145.         // Backup and get previous character.
  146.     
  147.     // ----- Run iteration
  148.     //     With run iteration, the client is responsible for translating between bytes and characters.
  149.     
  150.     void Advance(FW_ByteCount delta);
  151.         // Advance by delta bytes.
  152.         // It is client's responsiblity to ensure that delta bytes is a whole number of characters!
  153.         
  154.     void Backup(FW_ByteCount delta);
  155.         // Backup by delta bytes.
  156.         // It is client's responsiblity to ensure that delta bytes is a whole number of characters!
  157.     
  158.     void PeekRunAhead(const char*& start, FW_ByteCount& length);
  159.         // Peek ahead into current buffer of bytes without advancing.
  160.     
  161.     void PeekRunBehind(const char*& end, FW_ByteCount& length);
  162.         // Peek behind into current buffer of bytes without backing up.
  163.         // end points one past "current" byte!
  164.  
  165. private:
  166.  
  167.     void DelegateGetNextBuffer();
  168.         // Get another buffer from text data structure.
  169.         // Updates fStart and fLimit.
  170.         // Must ensure that fStart<=fLimit.
  171.  
  172.     void DelegateGetPreviousBuffer();
  173.         // Gets previous buffer from text data structure.
  174.         // Updates fStart and fLimit.
  175.         // Must ensure that fStart<=fLimit.
  176.     
  177. #ifdef FW_DEBUG
  178.     void ClassInvariants() const;
  179. #else
  180.     void ClassInvariants() const {}    // Let compiler optimize away the empty inline
  181. #endif
  182.  
  183. private:
  184.  
  185.     FW_HTextReader        fRep;
  186. };
  187.  
  188. //========================================================================================
  189. //    CLASS FW_CTextWriter
  190. //
  191. //    TextWriters are (intentionally) kept simpler than TextReaders.  We assume that there
  192. //    is no need to allow backing up in order to rewrite.  This results in a smaller and
  193. //    simpler interface.
  194. //========================================================================================
  195.  
  196. class FW_CTextWriter
  197. {
  198. public:
  199.     FW_DECLARE_AUTO(FW_CTextWriter)
  200.  
  201.     // ----- General
  202.     
  203.     virtual ~ FW_CTextWriter();
  204.         // Flush the current buffer.
  205.         // Writer destructors must do whatever may be necessary to restore text structure
  206.         // to valid state, e.g. restore NUL termination, cached length member, etc.
  207.  
  208.     FW_CTextWriter(FW_OTextRunWriter* adoptedWriter);
  209.     
  210.     FW_CTextWriter(FW_HTextWriter rep);
  211.     
  212.     operator FW_HTextWriter()
  213.         { return fRep; }
  214.     
  215.     FW_ByteCount GetPosition();
  216.         // Get the current byte position, where 0 is first position in data structure.
  217.  
  218.     // ----- Character-by-character iteration
  219.  
  220.     void PutCharacterAndAdvance(FW_LChar character, FW_ByteCount bytesInChar=0);
  221.         // Write the character into the data structure and advance to next position.
  222.         // If byte length of character is known, pass it along for efficiency.
  223.         // If byte length is not known, pass 0 and the length will be computed.
  224.  
  225.     // ----- Chunky iteration
  226.     
  227.     void WritePeek(char*& start, FW_ByteCount& length);
  228.         // Returns start address and length of buffer to write into.
  229.     
  230.     void WritePeekAdvance(char* start, FW_ByteCount bytesWritten);
  231.         // Inform iterator of number of bytes written into peek buffer
  232.         // start value must be same as returned by WritePeek
  233.         // No calls to PutCharacterAndAdvance between WritePeek and WritePeekAdvance!
  234.  
  235.     void FlushBuffer();
  236.         // Calls DoFlushBuffer to flush the current buffer, and updates fBufferSum.
  237.         // A subclass may want to call this function in it's destructor if it needs
  238.         // to defer final cleanup until after the buffer has been flushed.
  239.  
  240.   protected:
  241.   
  242.       void SetBufferSum(FW_ByteCount bufferSum);
  243.  
  244.     void DelegateFlushBuffer(const char* buffer, FW_ByteCount bytesToFlush);
  245.         // Flush the current buffer.
  246.  
  247.     void DelegateGetNextBuffer();
  248.         // Get another buffer from text data structure, update fNext and fLimit.
  249.     
  250.     void FlushAndGetNextBuffer();
  251.         // Calls FlushBuffer and DoGetNextBuffer.
  252.         // Called when the buffer has filled up.
  253.  
  254. private:
  255.     FW_HTextWriter        fRep;
  256. };
  257.  
  258. //========================================================================================
  259. //    CLASS FW_CMemoryReader
  260. //========================================================================================
  261.  
  262. class FW_CMemoryReader : public FW_CTextReader
  263. {
  264. public:
  265.     virtual ~FW_CMemoryReader();
  266.     FW_CMemoryReader(const char * buffer, FW_ByteCount bytes);
  267.     static FW_OMemoryRunReader* MakeReader(char * buffer, FW_ByteCount length);
  268. };
  269.  
  270. //========================================================================================
  271. //    CLASS FW_CMemoryWriter
  272. //
  273. //    A class for writing into a buffer of characters.
  274. //========================================================================================
  275.  
  276. class FW_CMemoryWriter : public FW_CTextWriter
  277. {
  278. public:
  279.     virtual ~FW_CMemoryWriter();
  280.     FW_CMemoryWriter(char * buffer, FW_ByteCount capacity);
  281.     static FW_OMemoryRunWriter* MakeWriter(char * buffer, FW_ByteCount capacity);
  282. };
  283.  
  284. #endif
  285.